package com.lalameow.researchstation.util

import net.minecraft.client.gui.DrawableHelper
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.client.util.math.Rect2i

typealias Size = Pair<Int, Int>
typealias Offset = Pair<Int, Int>

val Size.width: Int
    get() = first
val Size.height: Int
    get() = second

val Offset.x: Int
    get() = first
val Offset.y: Int
    get() = second

fun MatrixStack.translate(offset: Offset) = translate(offset.x, offset.y, 0)
fun MatrixStack.translate(rect: Rect2i) = translate(rect.x, rect.y, 0)
fun MatrixStack.translate(x: Number, y: Number) = translate(x, y, 0)
fun MatrixStack.translate(x: Number, y: Number, z: Number) = translate(x.toDouble(), y.toDouble(), z.toDouble())

fun MatrixStack.drawTexture(
    rect: Rect2i,
    textureOffset: Offset,
    textureSize: Size = 256 to 256
) =
    DrawableHelper.drawTexture(
        this,
        rect.x,
        rect.y,
        textureOffset.x.toFloat(),
        textureOffset.y.toFloat(),
        rect.width,
        rect.height,
        textureSize.width,
        textureSize.height
    )

fun MatrixStack.drawRepeating(rect: Rect2i, textureRect: Rect2i, textureSize: Size = Size(256, 256)) {
    var i = 0
    while (i < rect.width) {
        val cursorX = i + rect.x
        val cursorWidth = (rect.width - i).coerceAtMost(textureRect.width)
        var j = 0
        while (j < rect.height) {
            val cursorY = j + rect.y
            val cursorHeight = (rect.height - j).coerceAtMost(textureRect.height)
            drawTexture(
                Rect2i(cursorX, cursorY, cursorWidth, cursorHeight),
                textureRect.x to textureRect.y,
                textureSize
            )
            j += textureRect.height
        }
        i += textureRect.width
    }
}

fun MatrixStack.drawNineGridTexture(
    rect: Rect2i,
    textureRect: Rect2i,
    textureInnerRect: Rect2i,
    textureSize: Size = 256 to 256
) {
    push()
    translate(rect)
    val leftWidth = textureInnerRect.x
    val rightWidth = textureRect.width - textureInnerRect.right
    val topHeight = textureInnerRect.y
    val bottomHeight = textureRect.height - textureInnerRect.bottom
    // 左上角
    drawTexture(
        Rect2i(0, 0, leftWidth, topHeight),
        textureRect.x to textureRect.y,
        textureSize
    )
    // 右上角
    drawTexture(
        Rect2i(
            rect.width - rightWidth,
            0,
            rightWidth,
            topHeight
        ),
        textureRect.x + textureInnerRect.right to textureRect.y,
        textureSize
    )
    // 左下角
    drawTexture(
        Rect2i(
            0,
            rect.height - bottomHeight,
            leftWidth,
            bottomHeight
        ),
        textureRect.x to textureRect.y + textureInnerRect.bottom,
        textureSize
    )
    // 右下角
    drawTexture(
        Rect2i(
            rect.width - rightWidth,
            rect.height - bottomHeight,
            rightWidth,
            bottomHeight
        ),
        textureRect.x + textureInnerRect.right to textureRect.y + textureInnerRect.bottom,
        textureSize
    )

    val borderWidth = rect.width - leftWidth - rightWidth
    val borderHeight = rect.height - topHeight - bottomHeight

    // 上边
    drawRepeating(
        Rect2i(textureInnerRect.x, 0, borderWidth, topHeight),
        Rect2i(textureRect.x + textureInnerRect.x, textureRect.y, textureInnerRect.width, topHeight)
    )
    // 下边
    drawRepeating(
        Rect2i(textureInnerRect.x, borderHeight + topHeight, borderWidth, bottomHeight),
        Rect2i(
            textureRect.x + textureInnerRect.x,
            textureRect.y + textureInnerRect.bottom,
            textureInnerRect.width,
            bottomHeight
        )
    )
    // 左边
    drawRepeating(
        Rect2i(0, textureInnerRect.y, leftWidth, borderHeight),
        Rect2i(textureRect.x, textureRect.y + textureInnerRect.y, leftWidth, textureInnerRect.height)
    )
    // 右边
    drawRepeating(
        Rect2i(leftWidth + borderWidth, textureInnerRect.y, rightWidth, borderHeight),
        Rect2i(
            textureRect.x + textureInnerRect.right,
            textureRect.y + textureInnerRect.y,
            rightWidth,
            textureInnerRect.height
        )
    )

    // 内容颜色
    drawRepeating(
        Rect2i(textureInnerRect.x, textureInnerRect.y, borderWidth, borderHeight),
        Rect2i(
            textureRect.x + textureInnerRect.x,
            textureRect.y + textureInnerRect.y,
            textureInnerRect.width,
            textureInnerRect.height
        )
    )
    pop()
}
